﻿using System;
using System.Collections.Generic;
using System.Text;

using NBpn.TransferFunction;

namespace NBpn.Network
{
    public class Neuron : INeuron
    {
        protected INet net;

        public INet Net
        {
            get { return net; }
        }

        protected IList<Connection> forwardConnections;

        public IList<Connection> ForwardConnections
        {
            get { return forwardConnections; }
            //set { forwardConnections = value; }
        }
        protected IList<Connection> inputConnections;

        public IList<Connection> InputConnections
        {
            get { return inputConnections; }
            //set { inputConnections = value; }
        }
        private ITransferFunction transferFunction;

        public ITransferFunction TransferFunction
        {
            get { return transferFunction; }
            set { transferFunction = value; }
        }

        public Neuron()
        {
            forwardConnections = new List<Connection>();
            inputConnections = new List<Connection>();
            net = new Net(this);
        }

        public Neuron(IList<Connection> fowardConnections,
            IList<Connection> inputConnections,
            ITransferFunction transferFunction)
            : this()
        {
            this.transferFunction = transferFunction;
            this.forwardConnections = fowardConnections;
            this.inputConnections = inputConnections;
        }

        public Neuron(ITransferFunction transferFunction)
            : this(new List<Connection>(), new List<Connection>(),
                transferFunction)
        {

        }

        public Neuron(INet net)
            : this()
        {
            this.net = net;
        }

        public double Output
        {
            get
            {
                return GetOutput(net);
            }
        }

        protected double GetOutput(INet totalInput)
        {
            return this.transferFunction.Evaluate(totalInput);
        }

        public void ConnectWith(INeuron forwardNeuron, double weight)
        {
            Connection cnn = new Connection(this, forwardNeuron, weight);

            this.ForwardConnections.Add(cnn);

            forwardNeuron.InputConnections.Add(cnn);
        }

        public bool IsInputNeuron
        {
            get
            {
                return (this.inputConnections.Count == 1)
                    && (this.inputConnections[0].From == null);


            }

        }

    }
}
